10397
18054
Po przeczytaniu ukrytych funkcji i ciemnych rogów C ++ / STL na moderacji comp.lang.c ++. Byłem całkowicie zaskoczony, że następujący fragment został skompilowany i działał zarówno w Visual Studio 2008, jak i G ++ 4.4.
Oto kod:
#include 
int main ()
{
int x = 10;
while (x -> 0) // x idzie do 0
{
printf ("% d", x);
}
}
Wynik:
9 8 7 6 5 4 3 2 1 0
Zakładam, że to jest C, ponieważ działa również w GCC. Gdzie jest to zdefiniowane w normie i skąd się wzięło? 
-> nie jest operatorem. W rzeczywistości są to dwa oddzielne operatory - i>.
Kod warunku zmniejsza wartość x, zwracając oryginalną (nie zmniejszoną) wartość x, a następnie porównuje oryginalną wartość z 0 za pomocą operatora>.
Aby lepiej zrozumieć, oświadczenie można zapisać w następujący sposób:
podczas gdy ((x--)> 0)
|
Albo coś zupełnie innego ... x przesuwa się do 0.
podczas gdy (x - \
\
\
\
> 0)
printf ("% d", x);
Nie tak matematycznie, ale ... każdy obraz to tysiąc słów ...
|
To bardzo skomplikowany operator, więc nawet ISO / IEC JTC1 (Wspólny Komitet Techniczny 1) umieścił swój opis w dwóch różnych częściach standardu C ++.
Na marginesie, są to dwa różne operatory: - i> opisane odpowiednio w §5.2.6 / 2 i §5.9 standardu C ++ 03.
|
To odpowiednik
podczas gdy (x--> 0)
x-- (po zmniejszeniu) jest równoważne x = x-1, więc kod przekształca się w:
while (x> 0) {
x = x-1;
// logika
}
x--; // Dekrementacja postu wykonana, gdy x <= 0
|
x może dojść do zera jeszcze szybciej w przeciwnym kierunku:
int x = 10;
podczas gdy (0 <---- x)
{
printf ("% d", x);
}
8 6 4 2
Możesz kontrolować prędkość za pomocą strzałki!
int x = 100;
podczas gdy (0 <-------------------- x)
{
printf ("% d", x);
}
90 80 70 60 50 40 30 20 10
;)
|
Jego
#include 
int main (void) {
int x = 10;
while (x--> 0) {// x idzie do 0
printf ("% d", x);
}
return 0;
}
Tylko przestrzeń sprawia, że ​​rzeczy wyglądają śmiesznie, - zmniejsza się i> porównuje.
|
Użycie -> ma znaczenie historyczne. Zmniejszanie było (i nadal jest w niektórych przypadkach) szybsze niż zwiększanie w architekturze x86. Użycie -> sugeruje, że x zmierza do 0 i przemawia do osób z matematycznym doświadczeniem.
|
podczas gdy (x--> 0)
jak to jest analizowane.
|
Całkowicie maniakiem, ale będę używał tego:
#define as; while
int main (int argc, char * argv [])
{
int n = atoi (argv [1]);
do printf ("n to% d \ n", n) as (n -> 0);
return 0;
}
|
Jedna książka, którą przeczytałem (nie pamiętam dobrze, która książka) stwierdzała: Kompilatory próbują przeanalizować wyrażenia do największego tokenu, używając reguły lewej prawej.
W tym przypadku wyrażenie:
x -> 0
Analiza największych tokenów:
żeton 1: x
żeton 2: -
token 3:>
żeton 4: 0
wniosek: x--> 0
Ta sama zasada dotyczy tego wyrażenia:
a ----- b
Po przeanalizowaniu:
żeton 1: a
żeton 2: -
żeton 3: -
żeton 4: -
żeton 5: b
wniosek: (a -) - - b
Mam nadzieję, że pomoże to zrozumieć skomplikowane wyrażenie ^^
|
To jest dokładnie to samo co
podczas gdy (x--)
{
printf ("% d", x);
}
dla liczb nieujemnych
|
W każdym razie mamy teraz operatora „idzie do”. „->” jest łatwy do zapamiętania jako kierunek, a „gdy x idzie do zera” oznacza proste.
Co więcej, jest trochę bardziej wydajne niż „for (x = 10; x> 0; x -)” na niektórych platformach.
|
Ten kod najpierw porównuje x i 0, a następnie zmniejsza x. (Również powiedziane w pierwszej odpowiedzi: Post-dekrementujesz x, a następnie porównujesz x i 0 z operatorem>.) Zobacz wynik tego kodu:
9 8 7 6 5 4 3 2 1 0
Teraz najpierw porównujemy, a następnie zmniejszamy, widząc 0 na wyjściu.
Jeśli chcemy najpierw zmniejszyć, a następnie porównać, użyj tego kodu:
#include 
int main (nieważne)
{
int x = 10;
while (--x> 0) // x idzie do 0
{
printf ("% d", x);
}
return 0;
}
Ten wynik to:
9 8 7 6 5 4 3 2 1
|
Mój kompilator wydrukuje 9876543210, kiedy uruchomię ten kod.
#include 
int main ()
{
int x = 10;
while (x -> 0) // x idzie do 0
{
std :: cout << x;
}
}
Zgodnie z oczekiwaniami. While (x--> 0) w rzeczywistości oznacza while (x> 0). Dekrementacja x - post x.
podczas gdy (x> 0)
{
x--;
std :: cout << x;
}
to inny sposób pisania tej samej rzeczy.
Fajnie, że oryginał wygląda jak „podczas gdy x idzie do 0”.
|
Brakuje spacji między - i>. x jest dekrementowany po sprawdzeniu warunku x> 0?
|
- jest operatorem dekrementacji, a> jest operatorem większości.
Te dwa operatory są stosowane jako jeden, taki jak ->.
|
To połączenie dwóch operatorów. Pierwszy - służy do zmniejszania wartości, a> służy do sprawdzania, czy wartość jest większa niż argument po prawej stronie.
#include 
int main ()
{
int x = 10;
podczas gdy (x--> 0)
printf ("% d", x);
return 0;
}
Wynik będzie:
9 8 7 6 5 4 3 2 1 0
|
W rzeczywistości x jest post-dekrementacja i z tym warunkiem jest sprawdzany. To nie jest ->, to (x--)> 0
Uwaga: wartość x jest zmieniana po sprawdzeniu warunku, ponieważ następuje dekrementacja. Mogą również wystąpić podobne przypadki, na przykład:
-> x -> 0
++> x ++> 0
-> = x -> = 0
++> = x ++> = 0
|
C i C ++ przestrzegają zasady „maksymalnego munchu”. Tak samo jak a --- b jest tłumaczone na (a--) - b, w twoim przypadku x -> 0 przekłada się na (x -)> 0.
Reguła mówi zasadniczo, że przechodząc od lewej do prawej, wyrażenia są tworzone przez przyjęcie maksymalnej liczby znaków, które utworzą prawidłowe wyrażenie.
|
Po co te wszystkie komplikacje?
Prosta odpowiedź na pierwotne pytanie brzmi:
#include 
int main ()
{
int x = 10;
podczas gdy (x>0)
{
printf ("% d", x);
x = x-1;
}
}
Robi to samo. Nie mówię, że powinieneś to zrobić w ten sposób, ale robi to samo i odpowiedziałby na pytanie w jednym poście.
X-- jest po prostu skrótem powyższego, a> jest zwykłym operatorem większości. Żadnej wielkiej tajemnicy!
W dzisiejszych czasach zbyt wielu ludzi komplikuje proste rzeczy;)
|
W konwencjonalny sposób zdefiniowalibyśmy warunek w nawiasach while pętli () i warunek kończący w nawiasach klamrowych {}, ale -> definiuje oba naraz.
Na przykład:
int abc (nieważne)
{
int a = 5
while ((a--)> 0) // Zmniejszenie i porównanie jednocześnie
{
// Kod
}
}
To zmniejsza wartość a i uruchamia pętlę, gdy a jest większe niż 0.
Konwencjonalnie byłoby tak:
int abc (nieważne)
{
int a = 5;
podczas gdy (a> 0)
{
za--;
// Kod
}
za--;
}
W obie strony robimy to samo i osiągamy te same cele.
|
(x -> 0) oznacza (x--> 0).
Możesz użyć (x ->) Wyjście: 9 8 7 6 5 4 3 2 1 0
Możesz użyć (- x> 0) To średnia (--x> 0) Wynik: 9 8 7 6 5 4 3 2 1
Możesz użyć
(- \
\
x> 0)
Wyjście: 9 8 7 6 5 4 3 2 1
Możesz użyć
(\
\
x -> 0)
Wyjście: 9 8 7 6 5 4 3 2 1 0
Możesz użyć
(\
\
x -> 0
\
\
)
Wyjście: 9 8 7 6 5 4 3 2 1 0
Możesz też użyć
(
x
->
)
Wyjście: 9 8 7 6 5 4 3 2 1 0
Podobnie możesz wypróbować wiele metod, aby pomyślnie wykonać to polecenie.
|
Tutaj - jest jednoargumentowym operatorem dekrementacji postu.
while (x--> 0) // x idzie do 0
{
printf ("% d", x);
}
Na początku stan będzie oceniany jako
(x> 0) // 10> 0
Teraz, ponieważ warunek jest prawdziwy, przejdzie do pętli ze zmniejszoną wartością
x-- // x = 9
Dlatego pierwsza wydrukowana wartość to 9
I tak dalej. W ostatniej pętli x = 1, więc warunek jest prawdziwy. Zgodnie z operatorem jednoargumentowym wartość zmieniła się na x = 0 w momencie drukowania.
Teraz x = 0, co oznacza, że ​​warunek (x> 0) jest fałszywy, a pętla while kończy działanie.
|
To -> wcale nie jest operatorem. Mamy operator taki jak ->, ale nie taki jak ->. Jest to po prostu błędna interpretacja while (x--> 0), co oznacza po prostu, że x ma operator dekrementacji końcowej i ta pętla będzie działać, aż będzie większa od zera.
Innym prostym sposobem napisania tego kodu byłoby while (x--). Pętla while zatrzyma się, gdy otrzyma fałszywy warunek, a tutaj jest tylko jeden przypadek, tj. 0. Więc zatrzyma się, gdy wartość x zostanie zmniejszona do zera.
|
Bardzo aktywne pytanie. Zdobądź 10 punktów reputacji, aby odpowiedzieć na to pytanie. Wymóg dotyczący reputacji pomaga chronić to pytanie przed spamem i brakiem odpowiedzi.
Nie szukasz odpowiedzi? Przeglądaj inne pytania otagowane operatory c ++ c formatowanie kodu zgodność ze standardami lub zadaj własne pytanie.